#pragma once

/* A template (abst.) class (T - template parameter),
   that represents a container, which can hold pointers to T.
   Allows various operations on container, such as:
   insert(), remove(), find() and more.
*/
template <class T> class Container_t
{

protected:

	int numOfElements;

public:

	Container_t() {

		numOfElements = 0;
	}

	//copy CTOR.
	Container_t(const Container_t<T>& cont) : numOfElements(cont.numOfElements) {

	}

	virtual ~Container_t() {

	}

	//assignment operator for container.
	virtual Container_t<T>& operator=(const Container_t<T>& cont) {
		
		if (this != &cont) {  //to forbid a=a.
	
			numOfElements = cont.numOfElements;
		}
	
		return *this;
	}

	//returns number of elements in container.
	inline int count() const {

		return numOfElements;
	}

	/* seacrhes for a value in container, 
	   and returns pointer to it, if found (null ptr. if not). */
	virtual T* find(const T&) = 0;

	//inserts element at end of container.
	virtual void insert(T*) = 0;

	//appends element after given index in container.
	virtual void append(T*,int) = 0; 

	//prepends element before given index in container.
	virtual void prepend(T*,int) = 0;

	/* removes element from container, given its value (if found).
	   returns pointer to it, if found (null ptr. if not). */
	virtual T* remove(const T&) = 0;

	/* removes element from container, given its value (if found).
	   afterwards, deletes it. */
	virtual void removeAndDelete(const T&) = 0;

	//removes all elements from container.
	virtual void removeAll() = 0 {
		
		numOfElements = 0;
	}

	//removes and deletes all elements from container.
	virtual void removeAndDeleteAll() = 0 {

		numOfElements = 0;
	}
	
protected:
	
	//checks if given index is at array bounds, at curr. state.
	bool indexInBounds(int ind) const {

		return ( (ind >= 0) && (ind < count()) );
	}

};

